<?php
/**
 * CsvExporterWorker
 *
 * PHP version 5
 *
 * @category
 * @package
 * @author   Evgeny Utehin <utehin@ebola.com.ua>
 */

abstract class CsvExporterWorker
{
    /**
     * Delimiter & enclosure for fputscsv()
     *
     * @var string
     * @var string
     */
    public $delimiter    = ';';
    public $enclosure    = '"';

    /**
     * Flag saying use columns from CsvExporterWorker::_includedColumns only
     *
     * @var boolean
     */
    public $onlyIncluded = false;

    /**
     * Process data
     *
     * @var array
     * @var CActivedataProvider|CArrayDataProvider
     */
    protected $_data;
    protected $_dataProvider;

    /**
     * Included & excluded columns
     *
     * @var array
     * @var array
     */
    protected $_excludedColumns;
    protected $_includedColumns;

    /**
     * Report as string
     *
     * @var string
     */
    protected $_report;

    protected abstract function getReportHeaders();
    protected abstract function getHeader(&$headers, $value);
    protected abstract function getReportBody($fp);
    protected abstract function getIncludedColumnsData(&$rowData, $row);

    public function __construct($dataProvider, $includedColumns, $excludedColumns)
    {
        $dataProvider->setPagination(false);

        $this->_dataProvider = $dataProvider;
        $this->_data = $dataProvider->data;

        if (is_array($includedColumns) && is_array($excludedColumns)) {
            $this->_includedColumns = $includedColumns;
            $this->_excludedColumns = $excludedColumns;
        } else {
            throw new Exception(get_class($this) . ": IncludedColumns & ExcludedColumns"
                . " must be arrays");
        }
    }

    public function asText()
    {
        if (is_null($this->_report)) {
            $this->create();
        }

        return $this->_report;
    }

    public function asFile($path)
    {
        if ($path) {
            if (is_null($this->_report)) {
                $this->create();
            }

            if (file_put_contents($path, $this->_report)) {
                return true;
            } else {
                throw new Exception(get_class($this) . ": not create a file in the specified path.");
            }
        } else {
            throw new Exception(get_class($this) . ": path must be specified.");
        }
    }

    protected function create()
    {
        $fp = fopen("php://temp", 'w');

        fputcsv($fp, $this->getReportHeaders(), $this->delimiter, $this->enclosure);
        $this->getReportBody($fp);

        rewind($fp);
        $this->report = stream_get_contents($fp);

        fclose($fp);
    }
}
